package dfd.diagram.part;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.gmf.tooling.runtime.update.DiagramUpdater;

import dfd.Action;
import dfd.And;
import dfd.Dfd;
import dfd.DfdPackage;
import dfd.End;
import dfd.Node;
import dfd.Or;
import dfd.Process;
import dfd.Start;
import dfd.Storage;
import dfd.Transition;
import dfd.Xor;
import dfd.diagram.edit.parts.ActionEditPart;
import dfd.diagram.edit.parts.AndEditPart;
import dfd.diagram.edit.parts.DfdEditPart;
import dfd.diagram.edit.parts.EndEditPart;
import dfd.diagram.edit.parts.OrEditPart;
import dfd.diagram.edit.parts.ProcessEditPart;
import dfd.diagram.edit.parts.ProcessProcessActionEditPart;
import dfd.diagram.edit.parts.StartEditPart;
import dfd.diagram.edit.parts.StorageEditPart;
import dfd.diagram.edit.parts.TransitionEditPart;
import dfd.diagram.edit.parts.XorEditPart;
import dfd.diagram.providers.DfdElementTypes;

/**
 * @generated
 */
public class DfdDiagramUpdater {

	/**
	 * @generated
	 */
	public static List<DfdNodeDescriptor> getSemanticChildren(View view) {
		switch (DfdVisualIDRegistry.getVisualID(view)) {
		case DfdEditPart.VISUAL_ID:
			return getDfd_1000SemanticChildren(view);
		case ProcessProcessActionEditPart.VISUAL_ID:
			return getProcessProcessAction_7001SemanticChildren(view);
		}
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<DfdNodeDescriptor> getDfd_1000SemanticChildren(View view) {
		if (!view.isSetElement()) {
			return Collections.emptyList();
		}
		Dfd modelElement = (Dfd) view.getElement();
		LinkedList<DfdNodeDescriptor> result = new LinkedList<DfdNodeDescriptor>();
		for (Iterator<?> it = modelElement.getNodes().iterator(); it.hasNext();) {
			Node childElement = (Node) it.next();
			int visualID = DfdVisualIDRegistry.getNodeVisualID(view,
					childElement);
			if (visualID == AndEditPart.VISUAL_ID) {
				result.add(new DfdNodeDescriptor(childElement, visualID));
				continue;
			}
			if (visualID == XorEditPart.VISUAL_ID) {
				result.add(new DfdNodeDescriptor(childElement, visualID));
				continue;
			}
			if (visualID == StartEditPart.VISUAL_ID) {
				result.add(new DfdNodeDescriptor(childElement, visualID));
				continue;
			}
			if (visualID == OrEditPart.VISUAL_ID) {
				result.add(new DfdNodeDescriptor(childElement, visualID));
				continue;
			}
			if (visualID == EndEditPart.VISUAL_ID) {
				result.add(new DfdNodeDescriptor(childElement, visualID));
				continue;
			}
		}
		for (Iterator<?> it = modelElement.getChildren().iterator(); it
				.hasNext();) {
			Dfd childElement = (Dfd) it.next();
			int visualID = DfdVisualIDRegistry.getNodeVisualID(view,
					childElement);
			if (visualID == ProcessEditPart.VISUAL_ID) {
				result.add(new DfdNodeDescriptor(childElement, visualID));
				continue;
			}
			if (visualID == StorageEditPart.VISUAL_ID) {
				result.add(new DfdNodeDescriptor(childElement, visualID));
				continue;
			}
		}
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdNodeDescriptor> getProcessProcessAction_7001SemanticChildren(
			View view) {
		if (false == view.eContainer() instanceof View) {
			return Collections.emptyList();
		}
		View containerView = (View) view.eContainer();
		if (!containerView.isSetElement()) {
			return Collections.emptyList();
		}
		Process modelElement = (Process) containerView.getElement();
		LinkedList<DfdNodeDescriptor> result = new LinkedList<DfdNodeDescriptor>();
		for (Iterator<?> it = modelElement.getActions().iterator(); it
				.hasNext();) {
			Action childElement = (Action) it.next();
			int visualID = DfdVisualIDRegistry.getNodeVisualID(view,
					childElement);
			if (visualID == ActionEditPart.VISUAL_ID) {
				result.add(new DfdNodeDescriptor(childElement, visualID));
				continue;
			}
		}
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getContainedLinks(View view) {
		switch (DfdVisualIDRegistry.getVisualID(view)) {
		case DfdEditPart.VISUAL_ID:
			return getDfd_1000ContainedLinks(view);
		case AndEditPart.VISUAL_ID:
			return getAnd_2001ContainedLinks(view);
		case ProcessEditPart.VISUAL_ID:
			return getProcess_2002ContainedLinks(view);
		case XorEditPart.VISUAL_ID:
			return getXor_2003ContainedLinks(view);
		case StartEditPart.VISUAL_ID:
			return getStart_2004ContainedLinks(view);
		case OrEditPart.VISUAL_ID:
			return getOr_2005ContainedLinks(view);
		case EndEditPart.VISUAL_ID:
			return getEnd_2006ContainedLinks(view);
		case StorageEditPart.VISUAL_ID:
			return getStorage_2007ContainedLinks(view);
		case ActionEditPart.VISUAL_ID:
			return getAction_3001ContainedLinks(view);
		case TransitionEditPart.VISUAL_ID:
			return getTransition_4001ContainedLinks(view);
		}
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getIncomingLinks(View view) {
		switch (DfdVisualIDRegistry.getVisualID(view)) {
		case AndEditPart.VISUAL_ID:
			return getAnd_2001IncomingLinks(view);
		case ProcessEditPart.VISUAL_ID:
			return getProcess_2002IncomingLinks(view);
		case XorEditPart.VISUAL_ID:
			return getXor_2003IncomingLinks(view);
		case StartEditPart.VISUAL_ID:
			return getStart_2004IncomingLinks(view);
		case OrEditPart.VISUAL_ID:
			return getOr_2005IncomingLinks(view);
		case EndEditPart.VISUAL_ID:
			return getEnd_2006IncomingLinks(view);
		case StorageEditPart.VISUAL_ID:
			return getStorage_2007IncomingLinks(view);
		case ActionEditPart.VISUAL_ID:
			return getAction_3001IncomingLinks(view);
		case TransitionEditPart.VISUAL_ID:
			return getTransition_4001IncomingLinks(view);
		}
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getOutgoingLinks(View view) {
		switch (DfdVisualIDRegistry.getVisualID(view)) {
		case AndEditPart.VISUAL_ID:
			return getAnd_2001OutgoingLinks(view);
		case ProcessEditPart.VISUAL_ID:
			return getProcess_2002OutgoingLinks(view);
		case XorEditPart.VISUAL_ID:
			return getXor_2003OutgoingLinks(view);
		case StartEditPart.VISUAL_ID:
			return getStart_2004OutgoingLinks(view);
		case OrEditPart.VISUAL_ID:
			return getOr_2005OutgoingLinks(view);
		case EndEditPart.VISUAL_ID:
			return getEnd_2006OutgoingLinks(view);
		case StorageEditPart.VISUAL_ID:
			return getStorage_2007OutgoingLinks(view);
		case ActionEditPart.VISUAL_ID:
			return getAction_3001OutgoingLinks(view);
		case TransitionEditPart.VISUAL_ID:
			return getTransition_4001OutgoingLinks(view);
		}
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getDfd_1000ContainedLinks(View view) {
		Dfd modelElement = (Dfd) view.getElement();
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getContainedTypeModelFacetLinks_Transition_4001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getAnd_2001ContainedLinks(View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getProcess_2002ContainedLinks(
			View view) {
		Process modelElement = (Process) view.getElement();
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getContainedTypeModelFacetLinks_Transition_4001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getXor_2003ContainedLinks(View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getStart_2004ContainedLinks(View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getOr_2005ContainedLinks(View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getEnd_2006ContainedLinks(View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getStorage_2007ContainedLinks(
			View view) {
		Storage modelElement = (Storage) view.getElement();
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getContainedTypeModelFacetLinks_Transition_4001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getAction_3001ContainedLinks(View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getTransition_4001ContainedLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getAnd_2001IncomingLinks(View view) {
		And modelElement = (And) view.getElement();
		Map<EObject, Collection<EStructuralFeature.Setting>> crossReferences = EcoreUtil.CrossReferencer
				.find(view.eResource().getResourceSet().getResources());
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getIncomingTypeModelFacetLinks_Transition_4001(
				modelElement, crossReferences));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getProcess_2002IncomingLinks(View view) {
		Process modelElement = (Process) view.getElement();
		Map<EObject, Collection<EStructuralFeature.Setting>> crossReferences = EcoreUtil.CrossReferencer
				.find(view.eResource().getResourceSet().getResources());
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getIncomingTypeModelFacetLinks_Transition_4001(
				modelElement, crossReferences));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getXor_2003IncomingLinks(View view) {
		Xor modelElement = (Xor) view.getElement();
		Map<EObject, Collection<EStructuralFeature.Setting>> crossReferences = EcoreUtil.CrossReferencer
				.find(view.eResource().getResourceSet().getResources());
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getIncomingTypeModelFacetLinks_Transition_4001(
				modelElement, crossReferences));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getStart_2004IncomingLinks(View view) {
		Start modelElement = (Start) view.getElement();
		Map<EObject, Collection<EStructuralFeature.Setting>> crossReferences = EcoreUtil.CrossReferencer
				.find(view.eResource().getResourceSet().getResources());
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getIncomingTypeModelFacetLinks_Transition_4001(
				modelElement, crossReferences));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getOr_2005IncomingLinks(View view) {
		Or modelElement = (Or) view.getElement();
		Map<EObject, Collection<EStructuralFeature.Setting>> crossReferences = EcoreUtil.CrossReferencer
				.find(view.eResource().getResourceSet().getResources());
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getIncomingTypeModelFacetLinks_Transition_4001(
				modelElement, crossReferences));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getEnd_2006IncomingLinks(View view) {
		End modelElement = (End) view.getElement();
		Map<EObject, Collection<EStructuralFeature.Setting>> crossReferences = EcoreUtil.CrossReferencer
				.find(view.eResource().getResourceSet().getResources());
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getIncomingTypeModelFacetLinks_Transition_4001(
				modelElement, crossReferences));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getStorage_2007IncomingLinks(View view) {
		Storage modelElement = (Storage) view.getElement();
		Map<EObject, Collection<EStructuralFeature.Setting>> crossReferences = EcoreUtil.CrossReferencer
				.find(view.eResource().getResourceSet().getResources());
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getIncomingTypeModelFacetLinks_Transition_4001(
				modelElement, crossReferences));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getAction_3001IncomingLinks(View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getTransition_4001IncomingLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getAnd_2001OutgoingLinks(View view) {
		And modelElement = (And) view.getElement();
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getOutgoingTypeModelFacetLinks_Transition_4001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getProcess_2002OutgoingLinks(View view) {
		Process modelElement = (Process) view.getElement();
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getOutgoingTypeModelFacetLinks_Transition_4001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getXor_2003OutgoingLinks(View view) {
		Xor modelElement = (Xor) view.getElement();
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getOutgoingTypeModelFacetLinks_Transition_4001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getStart_2004OutgoingLinks(View view) {
		Start modelElement = (Start) view.getElement();
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getOutgoingTypeModelFacetLinks_Transition_4001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getOr_2005OutgoingLinks(View view) {
		Or modelElement = (Or) view.getElement();
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getOutgoingTypeModelFacetLinks_Transition_4001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getEnd_2006OutgoingLinks(View view) {
		End modelElement = (End) view.getElement();
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getOutgoingTypeModelFacetLinks_Transition_4001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getStorage_2007OutgoingLinks(View view) {
		Storage modelElement = (Storage) view.getElement();
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		result.addAll(getOutgoingTypeModelFacetLinks_Transition_4001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getAction_3001OutgoingLinks(View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<DfdLinkDescriptor> getTransition_4001OutgoingLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	private static Collection<DfdLinkDescriptor> getContainedTypeModelFacetLinks_Transition_4001(
			Dfd container) {
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		for (Iterator<?> links = container.getTransitions().iterator(); links
				.hasNext();) {
			EObject linkObject = (EObject) links.next();
			if (false == linkObject instanceof Transition) {
				continue;
			}
			Transition link = (Transition) linkObject;
			if (TransitionEditPart.VISUAL_ID != DfdVisualIDRegistry
					.getLinkWithClassVisualID(link)) {
				continue;
			}
			Node dst = link.getTarget();
			Node src = link.getSource();
			result.add(new DfdLinkDescriptor(src, dst, link,
					DfdElementTypes.Transition_4001,
					TransitionEditPart.VISUAL_ID));
		}
		return result;
	}

	/**
	 * @generated
	 */
	private static Collection<DfdLinkDescriptor> getIncomingTypeModelFacetLinks_Transition_4001(
			Node target,
			Map<EObject, Collection<EStructuralFeature.Setting>> crossReferences) {
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		Collection<EStructuralFeature.Setting> settings = crossReferences
				.get(target);
		for (EStructuralFeature.Setting setting : settings) {
			if (setting.getEStructuralFeature() != DfdPackage.eINSTANCE
					.getTransition_Target()
					|| false == setting.getEObject() instanceof Transition) {
				continue;
			}
			Transition link = (Transition) setting.getEObject();
			if (TransitionEditPart.VISUAL_ID != DfdVisualIDRegistry
					.getLinkWithClassVisualID(link)) {
				continue;
			}
			Node src = link.getSource();
			result.add(new DfdLinkDescriptor(src, target, link,
					DfdElementTypes.Transition_4001,
					TransitionEditPart.VISUAL_ID));
		}
		return result;
	}

	/**
	 * @generated
	 */
	private static Collection<DfdLinkDescriptor> getOutgoingTypeModelFacetLinks_Transition_4001(
			Node source) {
		Dfd container = null;
		// Find container element for the link.
		// Climb up by containment hierarchy starting from the source
		// and return the first element that is instance of the container class.
		for (EObject element = source; element != null && container == null; element = element
				.eContainer()) {
			if (element instanceof Dfd) {
				container = (Dfd) element;
			}
		}
		if (container == null) {
			return Collections.emptyList();
		}
		LinkedList<DfdLinkDescriptor> result = new LinkedList<DfdLinkDescriptor>();
		for (Iterator<?> links = container.getTransitions().iterator(); links
				.hasNext();) {
			EObject linkObject = (EObject) links.next();
			if (false == linkObject instanceof Transition) {
				continue;
			}
			Transition link = (Transition) linkObject;
			if (TransitionEditPart.VISUAL_ID != DfdVisualIDRegistry
					.getLinkWithClassVisualID(link)) {
				continue;
			}
			Node dst = link.getTarget();
			Node src = link.getSource();
			if (src != source) {
				continue;
			}
			result.add(new DfdLinkDescriptor(src, dst, link,
					DfdElementTypes.Transition_4001,
					TransitionEditPart.VISUAL_ID));
		}
		return result;
	}

	/**
	 * @generated
	 */
	public static final DiagramUpdater TYPED_INSTANCE = new DiagramUpdater() {
		/**
		 * @generated
		 */
		@Override
		public List<DfdNodeDescriptor> getSemanticChildren(View view) {
			return DfdDiagramUpdater.getSemanticChildren(view);
		}

		/**
		 * @generated
		 */
		@Override
		public List<DfdLinkDescriptor> getContainedLinks(View view) {
			return DfdDiagramUpdater.getContainedLinks(view);
		}

		/**
		 * @generated
		 */
		@Override
		public List<DfdLinkDescriptor> getIncomingLinks(View view) {
			return DfdDiagramUpdater.getIncomingLinks(view);
		}

		/**
		 * @generated
		 */
		@Override
		public List<DfdLinkDescriptor> getOutgoingLinks(View view) {
			return DfdDiagramUpdater.getOutgoingLinks(view);
		}
	};

}
